<!doctype html>
<!--
@license
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
  <meta charset="utf-8">
  <script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
  <script src="../../../web-component-tester/browser.js"></script>
  <link rel="import" href="../../polymer.html">
</head>
<body>

<dom-module id="x-dist">
  <template>
    x-dist
    <div id="distWrapper"><content id="content"></content></div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-dist-slot">
  <template>
    x-dist
    <div id="foo"><slot id="fooIP" name="foo"><div>fallback for foo</div></slot></div>
    <div id="default"><slot id="defaultIP"><div>fallback for default</div></slot></div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dist-slot'});
  });
  </script>
</dom-module>

<dom-module id="x-dist-simple">
  <template>
    <content id="content"></content>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dist-simple'});
  });
  </script>
</dom-module>

<dom-module id="x-dist-star">
  <template><content select="*"></content></template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dist-star'});
  });
  </script>
</dom-module>

<dom-module id="x-dist-inside-deep-tree">
  <template>
    x-dist-inside-deep-tree
    <div></div>
    <div>
      <div>
        <div>
          <div id="distWrapper"><content id="content"></content></div>
        </div>
      </div>
    </div>
    <div></div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dist-inside-deep-tree'});
  });
  </script>
</dom-module>

<dom-module id="x-no-dist">
  <template><span id="static">x-no-dist</span></template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-no-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-compose-dist">
  <template>
    <x-dist id="dist"></x-dist>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-compose-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-compose-no-dist">
  <template>
    <x-no-dist id="noDist"></x-no-dist>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-compose-no-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-dynamic-content">
  <template>
    <div>
      <div>
        <div>
          <div id="container">
            <template is="dom-if" id="domif">
              <content select=".insert" id="dynamicContent"></content>
            </template>
          </div>
        </div>
      </div>
    </div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dynamic-content'});
  });
  </script>
</dom-module>

<dom-module id="x-dynamic-content-wrapped">
  <template>
    <div>
      <template is="dom-if" id="domif">
        <div id="container">
          <content select=".insert"></content>
        </div>
      </template>
    </div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dynamic-content-wrapped'});
  });
  </script>
</dom-module>

<dom-module id="x-dynamic-content-redist">
  <template>
    <x-dynamic-content id="redistContainer">
      <template is="dom-if" id="redistDomif">
        <content select=".insert" id="redistContent"></content>
      </template>
    </x-dynamic-content>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dynamic-content-redist'});
  });
  </script>
</dom-module>

<dom-module id="x-dynamic-content-redist-element">
  <template>
    <template is="dom-if" id="redistDomif">
      <x-dist id="redistContainer">
        <content select=".insert" id="redistContent"></content>
      </x-dist>
    </template>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dynamic-content-redist-element'});
  });
  </script>
</dom-module>

<dom-module id="x-dynamic-content-and-dynamic-no-content">
  <template>
    <div id="container">
      <template is="dom-if" id="staticIf" restamp>
        <div id="static">satatic</div>
      </template>
      <template is="dom-if" id="contentIf" restamp>
        <content select="*"></content>
      </template>
    </div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-dynamic-content-and-dynamic-no-content'});
  });
  </script>
</dom-module>

<dom-module id="x-multi-dist">
  <template>
    <x-dist id="dist1"><content id="content1"></content></x-dist>
    <x-dist id="dist2"><content id="content2"></content></x-dist>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-multi-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-lazy-no-dist">
  <template>
    Lazy no dist!
  </template>
</dom-module>

<dom-module id="x-compose-lazy-no-dist">
  <template>
    <x-lazy-no-dist id="lazy">
      <content></content>
    </x-lazy-no-dist>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({is: 'x-compose-lazy-no-dist'});
  });
  </script>
</dom-module>

<dom-module id="x-toggle-if">
  <template>
    <div id="container1">
      <template id="foo" is="dom-if" if="{{foo}}" restamp>
        <span>foo</span>
        <content id="1.1" select="#one"></content>
        <content id="1.2" select="#two"></content>
      </template>
    </div>
    <div id="container2">
      <template id="notFoo" is="dom-if" if="{{!foo}}" restamp>
        <span>Not foo</span>
        <content id="2.1" select="#one"></content>
        <content id="2.2" select="#two"></content>
      </template>
    </div>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({
      is: 'x-toggle-if',
      properties: {
        foo: {
          type: Boolean,
          value: true
        }
      }
    });
  });
  </script>
</dom-module>

<dom-module id="x-repeat">
  <template>
    <x-dist-inside-deep-tree id="dist">
      <template is="dom-repeat" items="{{items}}"><div>{{item}}</div></template>
    </x-dist-inside-deep-tree>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({
      is: 'x-repeat',
      properties: {
        items: {
          type: Array,
          value: ["ITEM1", "ITEM2", "ITEM3"]
        }
      }
    });
  });
  </script>
</dom-module>

<dom-module id="x-repeat2">
  <template>
    <x-dist-star id="dist">
      <template is="dom-repeat" items="{{items}}">
        <div>{{item}}</div>
      </template>
    </x-dist-star>
  </template>
  <script>
  HTMLImports.whenReady(function() {
    Polymer({
      is: 'x-repeat2',
      properties: {
        items: {
          type: Array,
          value: ["ITEM1", "ITEM2", "ITEM3"]
        }
      }
    });
  });
  </script>
</dom-module>

<x-repeat2 id="repeat2"></x-repeat2>

<x-compose-lazy-no-dist><span>Child</span></x-compose-lazy-no-dist>


<script>

  var usingShady;

  suiteSetup(function() {
    // NOTE: these tests are mostly for Shady but running them on Shadow DOM
    // ensures Polymer.dom functions correctly under Shadow DOM.
    usingShady = !Polymer.Settings.useNativeShadow;
  });

  suite('appendChild & removeChild of <content>', function() {

    test('append div to distributing element', function() {
      var dist = document.createElement('x-dist');
      document.body.appendChild(dist);
      // Distribute div
      var div = document.createElement('div');
      Polymer.dom(dist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.firstElementChild, div);
      }
      // Append to distributed div
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.firstElementChild, div);
        assert.equal(div.firstElementChild, div2);
      }
      // Remove
      Polymer.dom(dist).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(dist);
    });

    test('append div to distributing element (auto <slot> to <content>)', function() {
      var dist = document.createElement('x-dist-slot');
      document.body.appendChild(dist);
      assert.equal(dist.$.fooIP.localName, 'content');
      assert.equal(dist.$.fooIP.getAttribute('select'), '[slot=\'foo\']');
      assert.equal(dist.$.defaultIP.localName, 'content');
      assert.equal(dist.$.defaultIP.getAttribute('select'), null);
      assert.equal(Polymer.dom(dist.$.fooIP).getDistributedNodes()[0].textContent, 'fallback for foo');
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[0].textContent, 'fallback for default');
      // Distribute div
      var frag = document.createDocumentFragment();
      var foo1 = frag.appendChild(document.createElement('div'));
      var default1 = frag.appendChild(document.createElement('div'));
      var foo2 = frag.appendChild(document.createElement('div'));
      var default2 = frag.appendChild(document.createElement('div'));
      var defaultText = frag.appendChild(document.createTextNode('distributed text'));
      foo1.setAttribute('slot', 'foo');
      foo2.setAttribute('slot', 'foo');
      Polymer.dom(dist).appendChild(frag);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(dist.$.fooIP).getDistributedNodes()[0], foo1);
      assert.equal(Polymer.dom(dist.$.fooIP).getDistributedNodes()[1], foo2);
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[0], default1);
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[1], default2);
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[2], defaultText);
      // Remove
      Polymer.dom(dist).removeChild(foo1);
      Polymer.dom(dist).removeChild(foo2);
      Polymer.dom(dist).removeChild(default1);
      Polymer.dom(dist).removeChild(default2);
      Polymer.dom(dist).removeChild(defaultText);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(dist.$.fooIP).getDistributedNodes()[0].textContent, 'fallback for foo');
      assert.equal(Polymer.dom(dist.$.fooIP).getDistributedNodes()[1], null);
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[0].textContent, 'fallback for default');
      assert.equal(Polymer.dom(dist.$.defaultIP).getDistributedNodes()[1], null);
      document.body.removeChild(dist);
    });

    test('append div to non-distributing element', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Distribute div
      var div = document.createElement('div');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.firstElementChild, noDist.$.static);
        assert.equal(noDist.children.length, 1);
      }
      // Append to distributed div
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.firstElementChild, noDist.$.static);
        assert.equal(noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(noDist).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.firstElementChild, noDist.$.static);
        assert.equal(noDist.children.length, 1);
      }
      document.body.removeChild(noDist);
    });

    test('append div to shady root of distributing element', function() {
      var dist = document.createElement('x-dist');
      document.body.appendChild(dist);
      // Append div to root
      var div = document.createElement('div');
      Polymer.dom(dist.root).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.nextElementSibling, div);
      }
      // Append to div in root
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.nextElementSibling, div);
        assert.equal(dist.$.distWrapper.nextElementSibling.firstElementChild, div2);
      }
      // Remove
      Polymer.dom(dist.root).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.nextElementSibling, null);
      }
      document.body.removeChild(dist);
    });

    test('append div to shady root of non-distributing element', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to root
      var div = document.createElement('div');
      Polymer.dom(noDist.root).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
      }
      // Append to div in root
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
        assert.equal(noDist.$.static.nextElementSibling.firstElementChild, div2);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, null);
      }
      document.body.removeChild(noDist);
    });

    test('append div to distributing element in root', function() {
      var compose = document.createElement('x-compose-dist');
      document.body.appendChild(compose);
      // Distribute div
      var div = document.createElement('div');
      Polymer.dom(compose.$.dist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, div);
      }
      // Append to distributed div
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, div);
        assert.equal(div.firstElementChild, div2);
      }
      // Remove
      Polymer.dom(compose.$.dist).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(compose);
    });

    test('append div to non-distributing element in root', function() {
      var compose = document.createElement('x-compose-no-dist');
      document.body.appendChild(compose);
      // Append div to root
      var div = document.createElement('div');
      Polymer.dom(compose.$.noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Append to div in root
      var div2 = document.createElement('div');
      Polymer.dom(div).appendChild(div2);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(compose.$.noDist).removeChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      document.body.removeChild(compose);
    });

    test('append content to shady root of element (div first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(noDist.root).appendChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content to shady root of element (content first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append content to shady root
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(noDist.root).appendChild(content);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content to div in shady root of element (div first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(noDist.$.static).appendChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.$.static).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content to div in shady root of element (content first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append content to shady root
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(noDist.$.static).appendChild(content);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.$.static).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content in fragment to shady root of element (div first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      frag.appendChild(content);
      Polymer.dom(noDist.root).appendChild(frag);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content in fragment to shady root of element (content first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      frag.appendChild(content);
      Polymer.dom(noDist.root).appendChild(frag);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append wrapped content to shady root of element (div first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(noDist.root).appendChild(frag);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, wrapper);
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append wrapped content to shady root of element (content first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(noDist.root).appendChild(frag);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.nextElementSibling, wrapper);
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.root).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append wrapped content to div in shady root of element (div first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(noDist.$.static).appendChild(frag);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, wrapper, 'wrong wrapper');
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.$.static).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append wrapped content to div in shady root of element (content first)', function() {
      var noDist = document.createElement('x-no-dist');
      document.body.appendChild(noDist);
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(noDist.$.static).appendChild(frag);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(noDist).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, wrapper, 'wrong wrapper');
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(noDist.$.static).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(noDist.$.static.firstElementChild, null);
      }
      document.body.removeChild(noDist);
    });

    test('append content to non-distributing element in shady root of composed element (div first)', function() {
      var compose = document.createElement('x-compose-no-dist');
      document.body.appendChild(compose);
      // Append content to light DOM of non-distributing element
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      // Append content to non-distributing element
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(compose.$.noDist).appendChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(compose.$.noDist).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      document.body.removeChild(compose);
    });

    test('append content to non-distributing element in shady root of composed element (content first)', function() {
      var compose = document.createElement('x-compose-no-dist');
      document.body.appendChild(compose);
      // Append content to light DOM of non-distributing element
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(compose.$.noDist).appendChild(content);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(compose.$.noDist).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      document.body.removeChild(compose);
    });

    test('append wrapped content to non-distributing element in shady root of composed element (div first)', function() {
      var compose = document.createElement('x-compose-no-dist');
      document.body.appendChild(compose);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(compose.$.noDist).appendChild(frag);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(compose.$.noDist).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      document.body.removeChild(compose);
    });

    test('append wrapped content to non-distributing element in shady root of composed element (content first)', function() {
      var compose = document.createElement('x-compose-no-dist');
      document.body.appendChild(compose);
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(compose.$.noDist).appendChild(frag);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      // Remove
      Polymer.dom(compose.$.noDist).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.noDist.firstElementChild, compose.$.noDist.$.static);
        assert.equal(compose.$.noDist.children.length, 1);
      }
      document.body.removeChild(compose);
    });

    test('append content to distributing element in shady root of composed element (div first)', function() {
      var compose = document.createElement('x-compose-dist');
      document.body.appendChild(compose);
      // Append content to light DOM of non-distributing element
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      // Append content to non-distributing element
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(compose.$.dist).appendChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(compose.$.dist).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(compose);
    });

    test('append content to distributing element in shady root of composed element (content first)', function() {
      var compose = document.createElement('x-compose-dist');
      document.body.appendChild(compose);
      // Append content to non-distributing element
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      Polymer.dom(compose.$.dist).appendChild(content);
      // Append content to light DOM of non-distributing element
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(compose.$.dist).removeChild(content);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(compose);
    });

    test('append wrapped content to distributing element in shady root of composed element (div first)', function() {
      var compose = document.createElement('x-compose-dist');
      document.body.appendChild(compose);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(compose.$.dist).appendChild(frag);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, wrapper);
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(compose.$.dist).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(compose);
    });

    test('append wrapped content to distributing element in shady root of composed element (content first)', function() {
      var compose = document.createElement('x-compose-dist');
      document.body.appendChild(compose);
      // Append content to shady root
      var frag = document.createDocumentFragment();
      var wrapper = document.createElement('div');
      var content = document.createElement('content');
      content.setAttribute('select', '.insert');
      wrapper.appendChild(content);
      frag.appendChild(wrapper);
      Polymer.dom(compose.$.dist).appendChild(frag);
      // Append div to light dom
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(compose).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, wrapper);
        assert.equal(wrapper.firstElementChild, div);
      }
      // Remove
      Polymer.dom(compose.$.dist).removeChild(wrapper);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(compose.$.dist.$.distWrapper.firstElementChild, null);
      }
      document.body.removeChild(compose);
    });

    test('append content to initially un-upgraded element', function() {
      var lazyContainer = document.querySelector('x-compose-lazy-no-dist');
      var child = Polymer.dom(lazyContainer).firstElementChild;
      Polymer({is: 'x-lazy-no-dist'});
      var content = document.createElement('content');
      Polymer.dom(lazyContainer.$.lazy.root).appendChild(content);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(content).getDistributedNodes()[1], child);
      if (lazyContainer.shadyRoot) {
        assert.equal(lazyContainer.$.lazy.lastElementChild, child);
      }
    });

    test('composed children distributed', function() {
      var host = document.createElement('x-dist');
      document.body.appendChild(host);
      var s0 = document.createElement('span');
      var frag = document.createDocumentFragment();
      var s1 = document.createElement('span');
      var s2 = document.createElement('span');
      var s3 = document.createElement('span');
      var composedChildren;
      frag.appendChild(s1);
      frag.appendChild(s2);
      frag.appendChild(s3);
      Polymer.dom(host).appendChild(s0);
      Polymer.dom(host).insertBefore(frag, s0);
      Polymer.dom.flush();
      if (host.shadyRoot) {
        assert.equal(host.$.distWrapper.children.length, 4);
        assert.equal(host.$.distWrapper.children[0], s1);
        assert.equal(host.$.distWrapper.children[1], s2);
        assert.equal(host.$.distWrapper.children[2], s3);
        assert.equal(host.$.distWrapper.children[3], s0);
        composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
        assert.equal(composedChildren.length, 4);
        assert.equal(composedChildren[0], s1);
        assert.equal(composedChildren[1], s2);
        assert.equal(composedChildren[2], s3);
        assert.equal(composedChildren[3], s0);
      }
      Polymer.dom(host).removeChild(s1);
      Polymer.dom(host).removeChild(s2);
      Polymer.dom(host).removeChild(s3);
      Polymer.dom.flush();
      if (host.shadyRoot) {
        assert.equal(host.$.distWrapper.children.length, 1);
        composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
        assert.equal(composedChildren.length, 1);
        assert.equal(composedChildren[0], s0);
      }
    });

    test('composed children added but not distributed', function() {
      var host = document.createElement('x-dist');
      document.body.appendChild(host);
      var s0 = document.createElement('span');
      var frag = document.createDocumentFragment();
      var s1 = document.createElement('span');
      var s2 = document.createElement('span');
      var s3 = document.createElement('span');
      var composedChildren;
      frag.appendChild(s1);
      frag.appendChild(s2);
      frag.appendChild(s3);
      Polymer.dom(host.$.distWrapper).appendChild(s0);
      Polymer.dom(host.$.distWrapper).insertBefore(frag, s0);
      Polymer.dom.flush();
      if (host.shadyRoot) {
        assert.equal(host.$.distWrapper.children.length, 4);
        assert.equal(host.$.distWrapper.children[0], s1);
        assert.equal(host.$.distWrapper.children[1], s2);
        assert.equal(host.$.distWrapper.children[2], s3);
        assert.equal(host.$.distWrapper.children[3], s0);
        composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
        assert.equal(composedChildren.length, 4);
        assert.equal(composedChildren[0], s1);
        assert.equal(composedChildren[1], s2);
        assert.equal(composedChildren[2], s3);
        assert.equal(composedChildren[3], s0);
      }
      Polymer.dom(host.$.distWrapper).removeChild(s1);
      Polymer.dom(host.$.distWrapper).removeChild(s2);
      Polymer.dom(host.$.distWrapper).removeChild(s3);
      Polymer.dom.flush();
      if (host.shadyRoot) {
        assert.equal(host.$.distWrapper.children.length, 1);
        composedChildren = Polymer.TreeApi.Composed.getChildNodes(host.$.distWrapper);
        assert.equal(composedChildren.length, 1);
        assert.equal(composedChildren[0], s0);
      }
    });

    test('moving children between distributing hosts', function() {
      var h1 = document.createElement('x-dist');
      var h2 = document.createElement('x-dist');
      document.body.appendChild(h1);
      document.body.appendChild(h2);
      Polymer.dom.flush();
      var d = document.createElement('div');
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
      document.body.removeChild(h2);
    });

    test('moving children between distributing hosts (parsed child)', function() {
      var div = document.createElement('div');
      div.innerHTML = '<x-dist><div></div></x-dist>';
      var h1 = div.firstChild;
      var h2 = document.createElement('x-dist');
      document.body.appendChild(div);
      document.body.appendChild(h2);
      Polymer.dom.flush();
      var d = Polymer.dom(h1).firstElementChild;
      assert.equal(d.localName, 'div');
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(div);
      document.body.removeChild(h2);
    });

    test('moving children between distributing host and fragment', function() {
      var h1 = document.createElement('x-dist');
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = document.createElement('div');
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving children between distributing host and fragment (parsed child)', function() {
      var div = document.createElement('div');
      div.innerHTML = '<x-dist><div></div></x-dist>';
      var h1 = div.firstChild;
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = Polymer.dom(h1).firstElementChild;
      assert.equal(d.localName, 'div');
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving children between distributing hosts with deep insertion points', function() {
      var h1 = document.createElement('x-dist-inside-deep-tree');
      var h2 = document.createElement('x-dist-inside-deep-tree');
      document.body.appendChild(h1);
      document.body.appendChild(h2);
      Polymer.dom.flush();
      var d = document.createElement('div');
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
      document.body.removeChild(h2);
    });

    test('moving children between distributing hosts with deep insertion points (parsed child)', function() {
      var div = document.createElement('div');
      div.innerHTML = '<x-dist-inside-deep-tree><div></div></x-dist-inside-deep-tree>';
      var h1 = div.firstChild;
      var h2 = document.createElement('x-dist-inside-deep-tree');
      document.body.appendChild(div);
      document.body.appendChild(h2);
      Polymer.dom.flush();
      var d = Polymer.dom(h1).firstElementChild;
      assert.equal(d.localName, 'div');
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h2.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(div);
      document.body.removeChild(h2);
    });

    test('moving children between distributing host with deep insertion and fragment', function() {
      var h1 = document.createElement('x-dist-inside-deep-tree');
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = document.createElement('div');
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving children between distributing host with deep insertion and fragment (parsed child)', function() {
      var div = document.createElement('div');
      div.innerHTML = '<x-dist-inside-deep-tree><div></div></x-dist-inside-deep-tree>';
      var h1 = div.firstChild;
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = Polymer.dom(h1).firstElementChild;
      assert.equal(d.localName, 'div');
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving children between distributing host with shallow insertion and fragment', function() {
      var h1 = document.createElement('x-dist-simple');
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = document.createElement('div');
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving children between distributing host with shallow insertion and fragment (parsed child)', function() {
      var div = document.createElement('div');
      div.innerHTML = '<x-dist-simple><div></div></x-dist-simple>';
      var h1 = div.firstChild;
      var h2 = document.createDocumentFragment();
      document.body.appendChild(h1);
      Polymer.dom.flush();
      var d = Polymer.dom(h1).firstElementChild;
      assert.equal(d.localName, 'div');
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      Polymer.dom(h1).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h1).childNodes.length, 1);
      assert.equal(Polymer.dom(h1).firstElementChild, d);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes(), [d]);
      assert.equal(Polymer.dom(h2).childNodes.length, 0);
      Polymer.dom(h2).appendChild(d);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(h2).childNodes.length, 1);
      assert.equal(Polymer.dom(h2).firstChild, d);
      assert.equal(Polymer.dom(h1).childNodes.length, 0);
      assert.deepEqual(Polymer.dom(h1.$.content).getDistributedNodes().length, 0);
      document.body.removeChild(h1);
    });

    test('moving an element containing a dom-repeat that distributes items', function() {
      var x1 = document.createElement('x-repeat');
      var div = document.createElement('div');
      Polymer.dom(document.body).appendChild(x1);
      Polymer.dom(document.body).appendChild(div);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(x1.$.dist).children.length, 4);
      if (x1.$.dist.shadyRoot) {
        assert.equal(x1.$.dist.$.distWrapper.children.length, 4);
      }
      Polymer.dom(div).appendChild(x1);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(x1.$.dist).children.length, 4);
      if (x1.$.dist.shadyRoot) {
        assert.equal(x1.$.dist.$.distWrapper.children.length, 4);
      }
      Polymer.dom(document.body).appendChild(x1);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(x1.$.dist).children.length, 4);
      if (x1.$.dist.shadyRoot) {
        assert.equal(x1.$.dist.$.distWrapper.children.length, 4);
      }
      Polymer.dom(div).appendChild(x1);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(x1.$.dist).children.length, 4);
      if (x1.$.dist.shadyRoot) {
        assert.equal(x1.$.dist.$.distWrapper.children.length, 4);
      }
      Polymer.dom(document.body).removeChild(div);
    });

    test('dom-repeat that distributes inside a select=* container', function(done) {
      var x1 = document.querySelector('#repeat2');
      Polymer.dom.flush();
      // async due to attachment.
      setTimeout(function() {
        assert.equal(Polymer.dom(x1.$.dist).children.length, 4);
        if (x1.$.dist.shadyRoot) {
          assert.equal(x1.$.dist.children.length, 4);
        }
        done();
      });
    });

    test('adding a document fragment clears nodes in the fragment', function() {
      var x = document.createElement('x-dist-star');
      var frag = document.createDocumentFragment();
      var t = document.createTextNode('hi');
      var d = document.createElement('div');
      frag.appendChild(t);
      frag.appendChild(d);
      Polymer.dom(x).appendChild(frag);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(t).parentNode, x, 'logical parent wrong');
      assert.equal(Polymer.dom(d).parentNode, x, 'logical parent wrong');
      assert.equal(frag.childNodes.length, 0, 'fragment not empty');
    });

    test('adding a non-distributing node removes the node from its current location', function() {
      var x = document.createElement('x-dist-star');
      var t = document.createTextNode('hi');
      document.body.appendChild(t);
      Polymer.dom(x).appendChild(t);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(t).parentNode, x);
      if (x.shadyRoot) {
        assert.isNull(t.parentNode);
      }
    });

  });

  suite('multi-content mutations', function() {

    test('remove, append first content', function() {
      var el = document.createElement('x-multi-dist');
      document.body.appendChild(el);
      // Append div
      var div = document.createElement('div');
      Polymer.dom(el).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, div);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, null);
      }
      // Remove first content
      Polymer.dom(el.$.dist1).removeChild(el.$.content1);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, null);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, div);
      }
      // Re-add a new first content
      Polymer.dom(el.$.dist1).appendChild(document.createElement('content'));
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, div);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, null);
      }
    });

    test('remove, append first distributing element', function() {
      var el = document.createElement('x-multi-dist');
      document.body.appendChild(el);
      // Append div
      var div = document.createElement('div');
      Polymer.dom(el).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, div);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, null);
      }
      // Remove first element with nested content
      Polymer.dom(el.root).removeChild(el.$.dist1);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, div);
      }
      // Re-add a new first content
      var frag = document.createDocumentFragment();
      var dist = document.createElement('x-dist');
      Polymer.dom(dist).appendChild(document.createElement('content'));
      frag.appendChild(dist);
      Polymer.dom(el.root).insertBefore(frag, el.$.dist2);
      // Note, special call required here
      el.distributeContent(true);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(dist.$.distWrapper.firstElementChild, div);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, null);
      }
    });

    test('move first distributing element', function() {
      var el = document.createElement('x-multi-dist');
      document.body.appendChild(el);
      // Append div
      var div = document.createElement('div');
      Polymer.dom(el).appendChild(div);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, div);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, null);
      }
      // Remove first element with nested content to the end
      Polymer.dom(el.root).appendChild(el.$.dist1);
      // Note, special call required here
      el.distributeContent(true);
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(el.$.dist1.$.distWrapper.firstElementChild, null);
        assert.equal(el.$.dist2.$.distWrapper.firstElementChild, div);
      }
    });

  });

  suite('dom-if append <content>', function() {

    test('x-dynamic-content', function() {
      var el = document.createElement('x-dynamic-content');
      document.body.appendChild(el);
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(el).appendChild(div);
      if (usingShady) {
        assert.ok(!el.querySelector('#container .insert'));
      }
      el.$.domif.if = true;
      el.$.domif.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.ok(el.querySelector('#container .insert'));
      }
      document.body.removeChild(el);
    });

    test('x-dynamic-content-wrapped', function() {
      var el = document.createElement('x-dynamic-content-wrapped');
      document.body.appendChild(el);
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(el).appendChild(div);
      if (usingShady) {
        assert(!el.querySelector('#container .insert'));
      }
      el.$.domif.if = true;
      el.$.domif.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.ok(el.querySelector('#container .insert'));
      }
      document.body.removeChild(el);
    });

    test('x-dynamic-content-redist', function() {
      var el = document.createElement('x-dynamic-content-redist');
      document.body.appendChild(el);
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(el).appendChild(div);
      if (usingShady) {
        assert.ok(!el.querySelector('#redistContainer .insert'));
      }
      el.$.redistDomif.if = true;
      el.$.redistContainer.$.domif.if = true;
      el.$.redistDomif.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.ok(el.querySelector('#redistContainer .insert'));
      }
      document.body.removeChild(el);
    });

    test('x-dynamic-content-redist-element', function() {
      var el = document.createElement('x-dynamic-content-redist-element');
      document.body.appendChild(el);
      var div = document.createElement('div');
      div.classList.add('insert');
      Polymer.dom(el).appendChild(div);
      if (usingShady) {
        assert(!el.querySelector('#redistContainer .insert'));
      }
      el.$.redistDomif.if = true;
      el.$.redistDomif.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.ok(el.querySelector('#redistContainer .insert'));
      }
      document.body.removeChild(el);
    });

    test('x-toggle-if', function() {
      var el = document.createElement('x-toggle-if');
      document.body.appendChild(el);
      var c1 = document.createElement('div');
      c1.id = 'one';
      Polymer.dom(el).appendChild(c1);
      var c2 = document.createElement('div');
      c2.id = 'two';
      Polymer.dom(el).appendChild(c2);
      el.$.foo.render();
      el.$.notFoo.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(c1.parentNode, el.$.container1);
        assert.equal(c2.parentNode, el.$.container1);
      }
      el.foo = false;
      el.$.foo.render();
      el.$.notFoo.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(c1.parentNode, el.$.container2);
        assert.equal(c2.parentNode, el.$.container2);
      }
      el.foo = true;
      el.$.foo.render();
      el.$.notFoo.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(c1.parentNode, el.$.container1);
        assert.equal(c2.parentNode, el.$.container1);
      }
      el.foo = false;
      el.$.foo.render();
      el.$.notFoo.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(c1.parentNode, el.$.container2);
        assert.equal(c2.parentNode, el.$.container2);
      }
      el.foo = true;
      el.$.foo.render();
      el.$.notFoo.render();
      Polymer.dom.flush();
      if (usingShady) {
        assert.equal(c1.parentNode, el.$.container1);
        assert.equal(c2.parentNode, el.$.container1);
      }
      document.body.removeChild(el);
    });

    test('x-dynamic-content-and-dynamic-no-content', function() {
      var el = document.createElement('x-dynamic-content-and-dynamic-no-content');
      document.body.appendChild(el);
      var c1 = document.createElement('div');
      c1.id = 'one';
      Polymer.dom(el).appendChild(c1);
      Polymer.dom.flush();
      assert.equal(Polymer.dom(el).querySelector('#one'), c1);
      assert.notOk(Polymer.dom(el.root).querySelector('#static'));
      assert.notOk(Polymer.dom(el.root).querySelector('content'));
      el.$.contentIf.if = true;
      el.$.staticIf.if = true;
      Polymer.dom.flush();
      assert.ok(Polymer.dom(el.root).querySelector('#static'));
      var ip = Polymer.dom(el.root).querySelector('content');
      assert.ok(ip);
      assert.equal(Polymer.dom(ip).getDistributedNodes()[0], c1);
      if (el.shadyRoot) {
        assert.ok(el.$.container.querySelector('#one'));
      }
      el.$.contentIf.if = false;
      el.$.staticIf.if = false;
      Polymer.dom.flush();
      assert.equal(Polymer.dom(el).querySelector('#one'), c1);
      assert.notOk(Polymer.dom(el.root).querySelector('#static'));
      assert.notOk(Polymer.dom(el.root).querySelector('content'));
      el.$.contentIf.if = true;
      el.$.staticIf.if = true;
      Polymer.dom.flush();
      assert.ok(Polymer.dom(el.root).querySelector('#static'));
      ip = Polymer.dom(el.root).querySelector('content');
      assert.ok(ip);
      assert.equal(Polymer.dom(ip).getDistributedNodes()[0], c1);
      if (el.shadyRoot) {
        assert.ok(el.$.container.querySelector('#one'));
      }
      document.body.removeChild(el);

    });

  });

</script>

</body>
</html>
